package com.abc.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.abc.config.ZhipuConfig;
import com.abc.dto.request.FileParseRequest;
import com.abc.dto.response.FileParseResultResponse;
import com.abc.dto.response.FileParseTaskResponse;
import com.abc.exception.BusinessException;
import com.abc.help.SessionHelper;
import com.abc.mapper.FileParseTaskMapper;
import com.abc.model.FileParseTaskModel;
import com.abc.service.ZhiPuFileParserService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

@Slf4j
@Service
public class ZhiPuFileParserServiceImpl implements ZhiPuFileParserService {

    private final RestTemplate restTemplate;
    private final ZhipuConfig zhipuConfig;
    private final FileParseTaskMapper fileParseTaskMapper;

    public ZhiPuFileParserServiceImpl(RestTemplate restTemplate, ZhipuConfig zhipuConfig, FileParseTaskMapper fileParseTaskMapper) {
        this.restTemplate = restTemplate;
        this.zhipuConfig = zhipuConfig;
        this.fileParseTaskMapper = fileParseTaskMapper;
    }

    @Override
    public FileParseTaskResponse createParseTask(FileParseRequest request) {
        long startTime = System.currentTimeMillis();
        FileParseTaskModel taskRecord = new FileParseTaskModel();

        try {
            // 记录请求参数
            taskRecord.setFileName(request.getFile().getOriginalFilename());
            taskRecord.setFileType(request.getFileType());
            taskRecord.setToolType(request.getToolType());
            taskRecord.setStatus("PROCESSING");
            taskRecord.setOperationType("CREATE_TASK");
            taskRecord.setUsername(SessionHelper.getUser());

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);
            headers.setBearerAuth(zhipuConfig.getApiKey());

            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();

            // 添加文件
            ByteArrayResource fileResource = new ByteArrayResource(request.getFile().getBytes()) {
                @Override
                public String getFilename() {
                    return request.getFile().getOriginalFilename();
                }
            };
            body.add("file", fileResource);
            body.add("tool_type", request.getToolType());
            body.add("file_type", request.getFileType());

            HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(body, headers);

            ResponseEntity<String> response = restTemplate.exchange(
                    zhipuConfig.getCreateTaskUrl(),
                    HttpMethod.POST,
                    entity,
                    String.class
            );

            long executionTime = System.currentTimeMillis() - startTime;
            taskRecord.setExecutionTime(executionTime);

            if (response.getStatusCode() == HttpStatus.OK) {
                JSONObject responseJson = JSON.parseObject(response.getBody());
                String taskId = responseJson.getString("task_id");

                // 记录任务创建结果（无论是否完成解析）
                taskRecord.setTaskId(taskId);
                taskRecord.setStatus("COMPLETED");
                taskRecord.setResponseResult(response.getBody());
                fileParseTaskMapper.insert(taskRecord);

                return new FileParseTaskResponse(taskId);
            } else {
                log.error("创建解析任务失败，状态码: {}, 响应: {}", response.getStatusCode(), response.getBody());

                // 记录失败结果
                taskRecord.setStatus("FAILED");
                taskRecord.setErrorMessage("HTTP状态码: " + response.getStatusCode() + ", 响应: " + response.getBody());
                fileParseTaskMapper.insert(taskRecord);

                throw new RuntimeException("创建解析任务失败");
            }

        } catch (Exception e) {
            long executionTime = System.currentTimeMillis() - startTime;
            log.error("创建解析任务异常", e);

            // 记录异常结果
            taskRecord.setStatus("FAILED");
            taskRecord.setErrorMessage("异常: " + e.getMessage());
            taskRecord.setExecutionTime(executionTime);
            fileParseTaskMapper.insert(taskRecord);

            throw new RuntimeException("创建解析任务异常: " + e.getMessage());
        }
    }

    @Override
    public FileParseResultResponse getParseResult(String taskId) {
        return getParseResultInternal(taskId, "text");
    }

    @Override
    public FileParseResultResponse getParseResultWithDownloadLinks(String taskId) {
        return getParseResultInternal(taskId, "download_link");
    }

    private FileParseResultResponse getParseResultInternal(String taskId, String formatType) {
        long startTime = System.currentTimeMillis();

        // 1. 先检查数据库中是否存在该 taskId
        FileParseTaskModel existingTask = fileParseTaskMapper.selectOne(
                Wrappers.<FileParseTaskModel>lambdaQuery()
                        .eq(FileParseTaskModel::getTaskId, taskId)
        );

        if (ObjectUtil.isEmpty(existingTask)) {
            log.warn("数据库中未找到 taskId: {}", taskId);
            throw new BusinessException("任务不存在，请先创建解析任务");
        }

        log.info("找到现有任务记录，taskId: {}, 当前状态: {}", taskId, existingTask.getStatus());

        // 2. 准备调用接口获取结果
        HttpHeaders headers = new HttpHeaders();
        headers.setBearerAuth(zhipuConfig.getApiKey());
        HttpEntity<String> entity = new HttpEntity<>(headers);

        String url = zhipuConfig.getResultUrl() + "/" + taskId + "/" + formatType;

        try {
            // 3. 调用智谱AI接口获取解析结果
            ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
            long executionTime = System.currentTimeMillis() - startTime;

            // 4. 解析响应结果
            FileParseResultResponse resultResponse = JSON.parseObject(response.getBody(), FileParseResultResponse.class);

            // 5. 更新数据库记录
            if (ObjectUtil.isEmpty(resultResponse.getContent()) && "text".equals(formatType)){
                log.error("获取解析结果失败，状态码: {}, 响应: {}", response.getStatusCode(), response.getBody());

                // 更新为失败状态
                existingTask.setStatus(resultResponse.getStatus());
                existingTask.setErrorMessage("获取解析结果失败: " + resultResponse.getMessage());
                existingTask.setResponseResult(response.getBody());
                existingTask.setExecutionTime(executionTime);
                existingTask.setOperationType("GET_TEXT_RESULT");
                fileParseTaskMapper.updateById(existingTask);
            } else{
                log.info("成功获取解析结果，taskId: {}", taskId);

                // 更新为成功状态
                existingTask.setStatus(resultResponse.getStatus());
                existingTask.setResponseResult(resultResponse.getContent());
                existingTask.setExecutionTime(executionTime);
                existingTask.setOperationType("text".equals(formatType) ? "GET_TEXT_RESULT" : "GET_DOWNLOAD_RESULT");
                existingTask.setErrorMessage(null); // 清除之前的错误信息
                fileParseTaskMapper.updateById(existingTask);
            }

            return resultResponse;

        } catch (Exception e) {
            long executionTime = System.currentTimeMillis() - startTime;
            log.error("调用解析结果接口异常，taskId: {}", taskId, e);
            // 更新为异常状态
            existingTask.setStatus("FAILED");
            existingTask.setErrorMessage("调用接口异常: " + e.getMessage());
            existingTask.setExecutionTime(executionTime);
            existingTask.setOperationType("text".equals(formatType) ? "GET_TEXT_RESULT" : "GET_DOWNLOAD_RESULT");
            fileParseTaskMapper.updateById(existingTask);

            throw new RuntimeException("获取解析结果异常: " + e.getMessage());
        }
    }
}